﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
using YasharEl.Infrastructure.Core.DomainModel.Users;
using YasharEl.Infrastructure.ExceptionHandling;
using YasharEl.Infrastructure.Diagnostics.Logging;
using YasharEl.Infrastructure.Core.PersistenceModel.Users.Repositories;
using YasharEl.Infrastructure.Core.Users;
using YasharEl.Infrastructure.Core.Personification;
using YasharEl.Infrastructure.Core.PersistenceModel.Users.Specifications;

namespace YasharEl.Infrastructure.Core.DomainModel.Implementation.Users
{
    public class UsersCatalog : IUsersCatalog
    {
        #region ReadOnly Fields

        private readonly IExceptionManager _exceptionManager;
        private readonly ILogger<UsersCatalog> _logger;
        private readonly IUsersRepository _usersRepository;

        #endregion

        #region Constructors

        public UsersCatalog(IExceptionManager exceptionManager, ILogger<UsersCatalog> logger, IUsersRepository usersRepository)
        {
            Contract.Requires<ArgumentNullException>(exceptionManager != null, "exceptionManager could not be null.");
            Contract.Requires<ArgumentNullException>(logger != null, "logger could not be null.");
            Contract.Requires<ArgumentNullException>(usersRepository != null, "usersRepository could not be null.");

            _exceptionManager = exceptionManager;
            _logger = logger;
            _usersRepository = usersRepository;
        }

        #endregion

        #region IUsersCatalog Impementations

        public IUser FindUserByIdentityNumber(long userIdentityNumber)
        {
            IUser foundUser = null;
            try
            {
                foundUser = _usersRepository
                    .Specify<IUserSpecification>()
                    .WithIdentityNumber(new IsraelIdentityNumber(userIdentityNumber))
                    .ToResult()
                    .SingleOrDefault();
            }
            catch (Exception e)
            {
                bool rethrow = _exceptionManager.HandleException(e, CoreConstants.DomainLayerExceptionPolicy);
                if (rethrow)
                {
                    throw;
                }
            }

            return foundUser;
        }

        #endregion
    }
}
